import React, { ReactNode, useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import { Button, Divider, message, Select, Tooltip } from 'antd'
import './Toolbar.less'
import Editor from './Editor'
import { mxCell } from 'mxgraph'

import folderOpenFilled from '@iconify/icons-ant-design/folder-open-filled'
import fileAddOutlined from '@iconify/icons-ant-design/file-add-outlined'
import saveOutlined from '@iconify/icons-ant-design/save-outlined'
import saveFilled from '@iconify/icons-ant-design/save-filled'

import arrowBendDownLeft from '@iconify/icons-ph/arrow-bend-down-left'
import arrowBendDownRight from '@iconify/icons-ph/arrow-bend-down-right'
import layerUpload from '@iconify/icons-gis/layer-upload'
import layerDownload from '@iconify/icons-gis/layer-download'
import objectGroup from '@iconify/icons-fa-regular/object-group'
import objectUngroup from '@iconify/icons-fa-regular/object-ungroup'
import zoomInOutlined from '@iconify/icons-ant-design/zoom-in-outlined'
import zoomOutOutlined from '@iconify/icons-ant-design/zoom-out-outlined'
import IconButton from '../components/Icon'
import EditorExecutor from '@/executor/EditorExecutor'
import ProjectDialog from '@/components/Dialogs/ProjectDialog'
import FileDialog from '@/components/Dialogs/FileDialog'
import * as FileApi from '@/api/file'

type FileDialogType = 'add' | 'edit' | 'saveas'

message.config({
  top: 60,
  duration: 2,
  maxCount: 3
})

const zoomOptions = [
  {
    label: '25%',
    value: 0.25
  },
  {
    label: '50%',
    value: 0.5
  },
  {
    label: '75%',
    value: 0.75
  },
  {
    label: '100%',
    value: 1
  },
  {
    label: '125%',
    value: 1.25
  },
  {
    label: '150%',
    value: 1.5
  }
]

interface IToolbarProps {
  editor: Editor
  updateDiagramData: (v: string | null) => {}
}

export default function Toolbar(props: IToolbarProps) {
  // 工程管理窗口可视
  const [projectDialogVisabled, setProjectDialogVisabled] = useState(false)
  // 文件窗口可见
  const [fileDialogVisabled, setFileDialogVisabled] = useState(false)
  // 对话框类型
  const [fileDialogType, setFileDialogType] = useState<'add' | 'saveas' | 'edit'>('edit')
  // 当前文件ID
  const [fileId, setFileId] = useState(0)
  // 组合按钮可用状态
  const [groupDisabled, setGroupDisabled] = useState(true)
  // 取消组合按钮可用状态
  const [ungroupDisabled, setUngroupDisabled] = useState(true)
  // 设置层级按钮的状态
  const [changeLayerDisabled, setChangeLayerDisabled] = useState(true)
  // 撤销按钮状态
  const [undoDisabled, setUndoDisabled] = useState(true)
  // 重做按钮状态
  const [redoDisabled, setRedoDisabled] = useState(true)

  /** 保存 */
  const onSave = () => {
    // const diagramXml: string | null = window.localStorage.getItem('autosaveXml')
    // props.updateDiagramData(diagramXml)
    // 如果是云端文件， 上传文件
    const { fileMeta } = EditorExecutor
    if (!fileMeta) {
      // 文件还没保存
      setFileDialogVisabled(true)
    } else if (fileMeta?.id) {
      // 文件已保存至云端
      onFileDialogOk(fileMeta, 'edit')
    }
    // 总是在本地存一份
    EditorExecutor.saveLocal()
  }

  //文件窗口点击确认
  const onFileDialogOk = async (meta: HFileMeta, dialogType: FileDialogType) => {
    setFileDialogVisabled(false)
    // 现金的情况
    let content = ''
    if (dialogType == 'add') {
      EditorExecutor.open({
        meta,
        content
      })
      // 如果工程管理窗口存在，关闭他
      projectDialogVisabled && setProjectDialogVisabled(false)
    }
    content = EditorExecutor.editor.getGraphXml()
    const file: HFile = {
      meta,
      content
    }

    saveCloudFile(file, dialogType == 'add')
  }

  // 打开文件信息对话框
  const openFileDialog = (type: 'add' | 'edit' | 'saveas', id?: number) => {
    // setProjectDialogVisabled(false)
    setFileDialogVisabled(true)
    setFileDialogType(type)
    id && setFileId(id)
  }

  /**
   * 保存文件到云端
   * @param meta
   */
  const saveCloudFile = async (file: HFile, isFirstSave: boolean = false) => {
    const { meta } = file
    if (!meta) {
      return
    }
    const fileResult = await FileApi.uploadXml(file.content, meta)
    if (fileResult && fileResult.code == 0) {
      meta.svgPath = fileResult.data.url
    }

    let saveResult
    if (!meta.id) {
      saveResult = await FileApi.createGraphFile(meta)
      meta.id = saveResult
    } else {
      saveResult = await FileApi.updateGraphFile(meta)
      // 更新文件信息数据成功，删掉老的的图形数据文件
      if (saveResult) {
        FileApi.deleteFile(fileResult.data.id)
      }
    }
    if (saveResult) {
      const msg = isFirstSave ? '文件新建成功！' : '文件保存成功！'
      message.success(msg)
      EditorExecutor.fileMeta = meta
    } else {
      message.error('文件保存失败！')
    }
  }

  //监听选中的图元变化
  const onCellChange = () => {
    const graph = EditorExecutor.graph
    const cells = graph.getSelectionCells()
    if (cells.length > 1) {
      setGroupDisabled(false)
      setUngroupDisabled(true)
      setChangeLayerDisabled(false)
    } else if (cells.length == 1) {
      if (
        !graph.getModel().isEdge(cells[0]) &&
        !graph.isSwimlane(cells[0]) &&
        graph.getModel().getChildCount(cells[0]) > 0
      ) {
        setGroupDisabled(true)
        setUngroupDisabled(false)
      }

      setChangeLayerDisabled(false)
    } else {
      setGroupDisabled(true)
      setUngroupDisabled(true)
      setChangeLayerDisabled(true)
    }

    const undoManager = EditorExecutor.editor.undoManager
    setUndoDisabled(!undoManager.canUndo())
    setRedoDisabled(!undoManager.canRedo())
  }

  useEffect(() => {
    if (props.editor) {
      EditorExecutor.graph.model.addListener(mxEvent.CHANGE, onCellChange)
      EditorExecutor.graph.getSelectionModel().addListener(mxEvent.CHANGE, onCellChange)

      return () => {
        EditorExecutor.graph.model.removeListener(onCellChange)
        EditorExecutor.graph.getSelectionModel().removeListener(onCellChange)
      }
    }
  }, [props.editor, groupDisabled, ungroupDisabled, undoDisabled, redoDisabled])

  return (
    <>
      <div key="toolbar" className="toolbar ">
        <IconButton
          icon={folderOpenFilled}
          tip="文件管理"
          className="c-black w-30px h-30px bg-#f6f7f8"
          onClick={() => {
            setProjectDialogVisabled(true)
          }}
        ></IconButton>
        <IconButton
          icon={fileAddOutlined}
          tip="新建文件"
          className="c-black w-30px h-30px bg-#f6f7f8"
          onClick={() => {
            openFileDialog('add')
          }}
        ></IconButton>
        <IconButton
          icon={saveOutlined}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="保存"
          onClick={() => {
            onSave()
          }}
        ></IconButton>
        <IconButton
          icon={saveFilled}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="另存为"
          onClick={() => {
            openFileDialog('saveas', EditorExecutor.fileMeta?.id)
          }}
        ></IconButton>
        <Divider type="vertical" className="h-90%" />
        <IconButton
          icon={arrowBendDownLeft}
          disabled={undoDisabled}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="撤销"
          onClick={() => {
            EditorExecutor.undo()
          }}
        ></IconButton>
        <IconButton
          icon={arrowBendDownRight}
          disabled={redoDisabled}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="重做"
          onClick={() => {
            EditorExecutor.redo()
          }}
        ></IconButton>
        <Divider type="vertical" className="h-90%" />
        <IconButton
          icon={objectGroup}
          disabled={groupDisabled}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="组合"
          onClick={() => {
            EditorExecutor.groupCells()
          }}
        ></IconButton>
        <IconButton
          icon={objectUngroup}
          disabled={ungroupDisabled}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="取消组合"
          onClick={() => {
            EditorExecutor.ungroupCells()
          }}
        ></IconButton>
        <Divider type="vertical" className="h-90%" />
        <IconButton
          icon={layerUpload}
          disabled={changeLayerDisabled}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="移至顶层"
          onClick={() => {
            EditorExecutor.graph.orderCells(false)
          }}
        ></IconButton>
        <IconButton
          icon={layerDownload}
          disabled={changeLayerDisabled}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="移至底层"
          onClick={() => {
            EditorExecutor.graph.orderCells(true)
          }}
        ></IconButton>
        <Divider type="vertical" className="h-90%" />
        <Select
          options={zoomOptions}
          defaultValue={1}
          className="h-23px mr-10px"
          onChange={(v) => {
            EditorExecutor.zoom(v)
          }}
        />
        <IconButton
          icon={zoomInOutlined}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="放大"
          onClick={() => {
            props.editor.graph.zoomIn()
          }}
        ></IconButton>
        <IconButton
          icon={zoomOutOutlined}
          fontSize={18}
          className="c-black w-30px h-30px bg-#f6f7f8"
          tip="缩小"
          onClick={() => {
            props.editor.graph.zoomOut()
          }}
        ></IconButton>

        <Button
          className="w-30px h-30px bg-#f6f7f8 border-width-0px"
          icon={
            <img
              className="icon mr-0px!"
              alt="zoom actual"
              src=""
            />
          }
          onClick={() => {
            props.editor.graph.zoomActual()
          }}
        ></Button>
        {/* <div
          className="toolbar-btn"
          onClick={(e) => {
            // e.currentTarget.classList.toggle('active')
            // this.panning = !this.panning
            // if (this.panning) {
            //   editor.startPanning()
            // } else {
            //   editor.stopPanning()
            // }
          }}
        >
          <img
            className="icon"
            alt="move"
            src=""
          />
          <span>move</span>
        </Button> */}
      </div>
      {projectDialogVisabled &&
        createPortal(
          <ProjectDialog
            onClose={() => setProjectDialogVisabled(false)}
            onEdit={(id) => openFileDialog('edit', id)}
            onNew={() => openFileDialog('add')}
          />,
          document.body
        )}
      {fileDialogVisabled &&
        createPortal(
          <FileDialog
            onClose={() => setFileDialogVisabled(false)}
            onOk={(meta) => {
              onFileDialogOk(meta, fileDialogType)
            }}
            type={fileDialogType}
            fileId={fileId}
          />,
          document.body
        )}
    </>
  )
}
